package ee.ut.sysmodel.bgmn.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import ee.ut.sysmodel.bgmn.model.BackgammonException;
import ee.ut.sysmodel.bgmn.model.Bar;
import ee.ut.sysmodel.bgmn.model.BoardState;
import ee.ut.sysmodel.bgmn.model.DiceResult;
import ee.ut.sysmodel.bgmn.model.Move;
import ee.ut.sysmodel.bgmn.model.Player;
import ee.ut.sysmodel.bgmn.model.Session;
import ee.ut.sysmodel.bgmn.Test;

public class Frame extends JFrame {
	private Session session;
	
	static Random test;
	static Image[] piece = new Image[2];
	static Image pin[] = new Image[4];
	static Image dice[] = new Image[6];
	static {
		test = new Random();
		ClassLoader cl = Frame.class.getClassLoader();
		try {
			piece[0] = ImageIO.read(cl.getResource("assets/piece1.png"));
			piece[1] = ImageIO.read(cl.getResource("assets/piece2.png"));
			pin[0] = ImageIO.read(cl.getResource("assets/pin1.png"));
			pin[1] = ImageIO.read(cl.getResource("assets/pin.png"));
			pin[3] = ImageIO.read(cl.getResource("assets/pin2.png"));
			pin[2] = ImageIO.read(cl.getResource("assets/pin3.png"));
			dice[0] = ImageIO.read(cl.getResource("assets/dice1.jpg"));
			dice[1] = ImageIO.read(cl.getResource("assets/dice2.jpg"));
			dice[2] = ImageIO.read(cl.getResource("assets/dice3.jpg"));
			dice[3] = ImageIO.read(cl.getResource("assets/dice4.jpg"));
			dice[4] = ImageIO.read(cl.getResource("assets/dice5.jpg"));
			dice[5] = ImageIO.read(cl.getResource("assets/dice6.jpg"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	static final int FONT_SIZE = 40;
	static final Font font = new Font("Courier", Font.BOLD, FONT_SIZE);
	
	JLabel playerOneLabel, playerTwoLabel;
	
	DiceButton[] diceButton;
	
	GoalButton[] goal;
	
	BarButton[] bar;
	
	JPanel mainPanel, rulesPanel, controlsPanel, gamePanel;
	
	int selectedPin;
	int SRC = -1;
	
	Map<Integer, PinButton> pinButton;
	Map<Integer, PinNumberButton> pinNumberButton;
	
	public Frame(Session sess) {
		
		super("BackgammonTheGame");
		
		this.session=sess;
		setSize(800,600);
		setResizable(false);
		
		setContentPane(mainMenu());
		
		setVisible(true);
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
	}
	
	
	
	private class MainMenuButton extends JButton {
		MainMenuButton(final JFrame frame, String name) {
			super(name);
			
			addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					String action = ((MainMenuButton)e.getSource()).getText();
					if (action.equals("Start")) {
						frame.setContentPane(gameMenu());
						frame.validate();
					} else if (action.equals("Rules")) {
						frame.setContentPane(rulesMenu());
						frame.validate();
					} else if (action.equals("Controls")) {
						frame.setContentPane(controlsMenu());
						frame.validate();
						
					} else if (action.equals("Back")) {
						frame.setContentPane(mainMenu());
						frame.validate();
					} else if (action.equals("Exit")) {
						frame.dispose();
						//System.exit(0);
					} else if (action.equals("THROW DICE")) {
						
						//System.exit(0);
					} else if (action.equals("START OVER")){
						frame.dispose();
						System.out.println("New game");
						Test t = new Test();
						t.start();
					}
				}
			});
		}
	}

	private Container mainMenu() {
		if (mainPanel == null) {
			mainPanel = new JPanel();
			mainPanel.setLayout(new BorderLayout());
			mainPanel.add(Box.createHorizontalStrut(200), BorderLayout.WEST);
			
			JPanel mainMenuButtons = new JPanel();
			mainMenuButtons.setLayout(new GridLayout(9,1));
			mainMenuButtons.add(Box.createVerticalStrut(200));
			
			mainMenuButtons.add(new MainMenuButton(this, "Start"));
			mainMenuButtons.add(Box.createVerticalGlue());
			mainMenuButtons.add(new MainMenuButton(this, "Rules"));
			mainMenuButtons.add(Box.createVerticalGlue());
			mainMenuButtons.add(new MainMenuButton(this, "Controls"));
			mainMenuButtons.add(Box.createVerticalGlue());
			mainMenuButtons.add(new MainMenuButton(this, "Exit"));
			mainMenuButtons.add(Box.createVerticalStrut(200));
			
			mainPanel.add(mainMenuButtons, BorderLayout.CENTER);
			mainPanel.add(Box.createHorizontalStrut(200), BorderLayout.EAST);
		}
		return mainPanel;
	}
	
	private Container rulesMenu() {
		if (rulesPanel == null) {
			String ruleContents = "No rules loaded";
			try {
				ruleContents = readFile("./assets/rules.txt");
			} catch (IOException e) {
				System.out.println("Reading rules file failed");
				e.printStackTrace();
			}
			rulesPanel = new JPanel();
			rulesPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
			rulesPanel.setLayout(new BorderLayout());
			JPanel buttonSidePanel = new JPanel();
			buttonSidePanel.setLayout(new BoxLayout(buttonSidePanel, BoxLayout.PAGE_AXIS));
			buttonSidePanel.add(new MainMenuButton(this, "Back"));
			buttonSidePanel.add(Box.createHorizontalStrut(100));
			rulesPanel.add(buttonSidePanel, BorderLayout.WEST);
			TextArea rulesText = new TextArea(ruleContents,4,30,TextArea.SCROLLBARS_VERTICAL_ONLY);
			rulesText.setEditable(false);
			rulesPanel.add(rulesText, BorderLayout.CENTER);
			rulesPanel.add(Box.createHorizontalStrut(100), BorderLayout.EAST);
		}
		return rulesPanel;
	}
	
	private Container controlsMenu() {
		if (controlsPanel == null) {
			String ruleContents = "No controls loaded";
			try {
				ruleContents = readFile("./assets/controls.txt");
			} catch (IOException e) {
				System.out.println("Reading controls file failed");
				e.printStackTrace();
			}
			controlsPanel = new JPanel();
			controlsPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
			controlsPanel.setLayout(new BorderLayout());
			JPanel buttonSidePanel = new JPanel();
			buttonSidePanel.setLayout(new BoxLayout(buttonSidePanel, BoxLayout.PAGE_AXIS));
			buttonSidePanel.add(new MainMenuButton(this, "Back"));
			buttonSidePanel.add(Box.createHorizontalStrut(100));
			controlsPanel.add(buttonSidePanel, BorderLayout.WEST);
			TextArea controlsText = new TextArea(ruleContents,4,30,TextArea.SCROLLBARS_VERTICAL_ONLY);
			controlsText.setEditable(false);
			controlsPanel.add(controlsText, BorderLayout.CENTER);
			controlsPanel.add(Box.createHorizontalStrut(100), BorderLayout.EAST);
		}
		return controlsPanel;
	}
	
	private class PinButton extends JButton {
		
		final static int PIECE_SPACING = 5;

		int nr;
		Session session;
		
		private Frame frame;
		
		PinButton(final Frame frame, final Session session,int nr) {
			this.nr = nr;
			this.session = session;
			this.frame = frame;
			
			setFocusable(false);
			setBackground(Color.white);
			
			
			//setText(Integer.toString(nr));
			if (nr <= 12) {
				if (nr % 2 == 0) setIcon(new ImageIcon(pin[1]));
				else setIcon(new ImageIcon(pin[3]));
			} else {
				if (nr % 2 == 0) setIcon(new ImageIcon(pin[0]));
				else setIcon(new ImageIcon(pin[2]));
			}
			setBorder(BorderFactory.createEmptyBorder());
			//setBorder(BorderFactory.createLineBorder(Color.white));
			
			addMouseListener(new MouseAdapter() {
				@Override
				public void mouseEntered(MouseEvent e) {
					int thisNr = ((PinButton)e.getSource()).nr;
					if (thisNr != selectedPin) setBackground(Color.lightGray);
					markAvailableMoves(thisNr, Color.yellow);
					frame.repaint();
				}
				@Override
				public void mouseExited(MouseEvent e) {
					int thisNr = ((PinButton)e.getSource()).nr;
					if (thisNr != selectedPin) setBackground(Color.white);
					else setBackground(Color.green);
					markAvailableMoves(thisNr, Color.white);
					frame.repaint();
				}
				
				@Override
				public void mousePressed(MouseEvent e) {
					int thisNr = ((PinButton)e.getSource()).nr;
					if (selectedPin == thisNr) {
						setBackground(Color.lightGray);
						selectedPin = 0;
					} else {
						
						if (selectedPin != 0 && SRC!=-1)
							pinButton.get(new Integer(selectedPin))
										.setBackground(Color.white);
						selectedPin = thisNr;
						setBackground(Color.green);
						tryToMove(session, thisNr);
					}
					updatePins();
				}
				
				
			});
		}
		
		private void tryToMove(final Session session, int thisNr) {
			if(SRC==-1 || SRC==thisNr){
				SRC = thisNr;
			} else {
				List<Move> moves;
				if (session.getCurrentPlayer().getBarCount() > 0) {
					int bar;
					if (session.getCurrentPlayer().getIdentity() == Player.Identity.PLAYER_ONE) {
						bar = BoardState.P1_SOURCE_BAR;
					} else {
						bar = BoardState.P2_SOURCE_BAR;
					}
					moves = session.getAvailableMoves(bar);
				} else {
					moves = session.getAvailableMoves(SRC);
				}
				for(Move m : moves){
					if(m.getTarget().getNumber()==thisNr){
						try {
							session.makeMove(m);
							
							pinButton.get(new Integer(selectedPin))
							.setBackground(Color.white);
							selectedPin=0;
							SRC=-1;
							
							if(session.isTurnFinished()) {
								session.switchTurns();
								frame.repaint();
								updateDice(session);
							}
						} catch (BackgammonException e1) {
							e1.printStackTrace();
						}
						
						break;
					}
				}
				SRC=thisNr;
				
			}
		}

		private void updateDice(final Session session) {
			for (int i = 0; i < 4; i++) {
				diceButton[i].empty();
				diceButton[i].setEnabled(true);
			}
			
			DiceResult[] diceResults = session.getDiceValues();
			for (int i = 0; i < diceResults.length; i++) {
				diceButton[i].setValue(diceResults[i].getResult());
			}
		}

		@Override
		public void paint(Graphics g) {
			super.paint(g);
			int piece_owner = 0, piece_count = 0;
			if(session.getBoardState().getPin(nr).getOwner()!=null){
				piece_owner=session.getBoardState().getPin(nr).getOwner().getIdentity().ordinal();
				piece_count=session.getBoardState().getPin(nr).getPieceCount();
			}
			
			int y = 0;
			int x = getWidth()/2-piece[piece_owner].getWidth(null)/2;
			if (piece_count < 9) {
				for (int i = 0; i < piece_count; i++) {
					
					if (nr > 12) {
						y = PIECE_SPACING+i*(PIECE_SPACING+piece[piece_owner].getHeight(null));
						g.drawImage(piece[piece_owner], x, y, null);
					} else {
						y = getHeight()-(i+1)*(PIECE_SPACING+piece[piece_owner].getHeight(null));
						g.drawImage(piece[piece_owner], x, y, null);
					}
				}
			} else {
				if (nr > 12) {
					y = PIECE_SPACING;
					g.drawImage(piece[piece_owner], x, y, null);
					y += 50+piece[piece_owner].getHeight(null);
				} else {
					y = getHeight()-(PIECE_SPACING+piece[piece_owner].getHeight(null));
					g.drawImage(piece[piece_owner], x, y, null);
					y -= 50-piece[piece_owner].getHeight(null);
				}
				x = (int) (getWidth()/2-font.getStringBounds(Integer.toString(piece_count),
						((Graphics2D)g).getFontRenderContext()).getWidth()/2);
				if (piece_owner == 0) g.setColor(Color.orange);
				else g.setColor(Color.cyan);
				g.setFont(font);
				g.drawString(Integer.toString(piece_count), x, y);
			}
		}
	}
	
	private void markAvailableMoves(int thisNr, Color color) {
		List<Move> moveList = session.getAvailableMoves(thisNr);

		for(Move move : moveList){
			int srcNumber = move.getSource().getNumber();
			if (srcNumber == thisNr && move.getTarget().getNumber()!=Bar.P1_BAR_POSITION && move.getTarget().getNumber()!=Bar.P2_BAR_POSITION) {
				pinNumberButton.get(new Integer(move.getTarget().getNumber()))
				.setBackground(color);
			}
			if(move.getTarget().getNumber()<=Bar.P1_BAR_POSITION ){
				// TODO: here we have to higlight bottom bar
				String test="sad";
			} 
			if(move.getTarget().getNumber()>=Bar.P2_BAR_POSITION){
				// TODO: here we have to higlight  top bar
				String test="sa";
			}
		}
	}
	
	private void markAvailableMovesFromBar(Color color) {
		List<Move> moveList;
		if (session.getCurrentPlayer().getBarCount() > 0) {
			int bar;
			if (session.getCurrentPlayer().getIdentity() == Player.Identity.PLAYER_ONE) {
				bar = BoardState.P1_SOURCE_BAR;
			} else {
				bar = BoardState.P2_SOURCE_BAR;
			}
			moveList = session.getAvailableMoves(bar);
		} else {
			return;
		}
		
		for(Move move : moveList){
			pinNumberButton.get(new Integer(move.getTarget().getNumber()))
				.setBackground(color);
		}
	}
	
	private class BarButton extends JButton {
		
		int owner = 0;
		
		BarButton(int owner, Session session) {
			this.owner = owner;
			setText(" ");
			setFocusable(false);
			setBackground(Color.black);
			setBorder(BorderFactory.createEmptyBorder());
			addMouseListener(new MouseAdapter() {
				@Override
				public void mouseEntered(MouseEvent arg0) {
					setBackground(Color.lightGray);
					markAvailableMovesFromBar(Color.yellow);
				}
				@Override
				public void mouseExited(MouseEvent arg0) {
					setBackground(Color.black);
					markAvailableMovesFromBar(Color.white);
				}
			});
		}

		@Override
		public void paint(Graphics g) {
			int piece_count = 0;
			if(session.getCurrentPlayer().getIdentity().ordinal()==owner){
				piece_count = session.getCurrentPlayer().getBarCount();
			} else{
				piece_count = session.getOpponentPlayer().getBarCount();
			}
			super.paint(g);
			if (piece_count > 0) {
				int y = 0;
				int x = getWidth()/2-piece[owner].getWidth(null)/2;
				if (owner == 0) {
					y = PinButton.PIECE_SPACING;
					g.drawImage(piece[owner], x, y, null);
					y += 50+piece[owner].getHeight(null);
				} else {
					y = getHeight()-(PinButton.PIECE_SPACING+piece[owner].getHeight(null));
					g.drawImage(piece[owner], x, y, null);
					y -= 50-piece[owner].getHeight(null);
				}
				x = (int) (getWidth()/2-font.getStringBounds(Integer.toString(piece_count),
						((Graphics2D)g).getFontRenderContext()).getWidth()/2);
				if (owner == 0) g.setColor(Color.orange);
				else g.setColor(Color.cyan);
				g.setFont(font);
				g.drawString(Integer.toString(piece_count), x, y);
			}
		}
	}
	
	private class GoalButton extends JButton {
		
		int owner;
		
		GoalButton(int owner,Session session) {
			this.owner = owner;
			setText("Click on this to add checkers to goal");
			setFocusable(false);
			setBackground(Color.white);
			setPreferredSize(new Dimension(PinButton.PIECE_SPACING+15*(piece[owner].getWidth(null)+PinButton.PIECE_SPACING),30));
			//setBorder(BorderFactory.createEmptyBorder());
			
			addMouseListener(new MouseAdapter() {
				@Override
				public void mouseEntered(MouseEvent e) {
					setBackground(Color.lightGray);
				}
				@Override
				public void mouseExited(MouseEvent e) {
					setBackground(Color.white);
				}
				
				@Override
				public void mouseClicked(MouseEvent e) {
					setText("");
				}
				
			});
		}

		@Override
		public void paint(Graphics g) {
			super.paint(g);
			int piece_count = 0;
			if(session.getCurrentPlayer().getIdentity().ordinal()==owner){
				piece_count = session.getCurrentPlayer().getGoalCount();
			} else{
				piece_count = session.getOpponentPlayer().getGoalCount();
			}
			int y = getHeight()/2-piece[owner].getHeight(null)/2;
			int x = 0;
			
			for (int i = 0; i < piece_count; i++) {
				x = PinButton.PIECE_SPACING+i*(PinButton.PIECE_SPACING+piece[owner].getWidth(null));
				g.drawImage(piece[owner], x, y, null);
			}
		}
	}
	
	private class DiceButton extends JButton {
		
		int value = 0;
		
		DiceButton() {
			setBackground(Color.white);
			
			addMouseListener(new MouseAdapter() {
				@Override
				public void mouseEntered(MouseEvent e) {
					int val = selectedPin;
					Player identity = null;
					if (selectedPin > 0)
						identity = session.getBoardState().getPin(selectedPin).getOwner();
					if (((JButton)e.getSource()).isEnabled() &&
							identity != null &&
							identity.getIdentity() == session.getCurrentPlayer().getIdentity()) {
						markPin(val, Color.red);
					}
					updatePins();
				}
				@Override
				public void mouseExited(MouseEvent e) {
					int val = selectedPin;
					Player identity = null;
					if (selectedPin > 0)
						identity = session.getBoardState().getPin(selectedPin).getOwner();
					if (((JButton)e.getSource()).isEnabled() &&
							identity != null &&
							identity.getIdentity() == session.getCurrentPlayer().getIdentity()) {
						markPin(val, Color.white);
					}
					updatePins();
				}
				
				void markPin(int val, Color color) {
					if (session.getCurrentPlayer().getIdentity() == Player.Identity.PLAYER_ONE)
						val += value;
					else
						val -= value;

					System.out.println(val);
					Move move = findMove(selectedPin, val);
					if (move != null)
						pinButton.get(new Integer(val)).setBackground(color);
				}
			});
			
			addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					int val = selectedPin;
					Player identity = null;
					if (selectedPin > 0)
						identity = session.getBoardState().getPin(selectedPin).getOwner();
					if (((JButton)e.getSource()).isEnabled() &&
							identity != null &&
							identity.getIdentity() == session.getCurrentPlayer().getIdentity()) {
						makeMove(val);
					}
				}
				
				void makeMove(int val) {
					if (session.getCurrentPlayer().getIdentity() == Player.Identity.PLAYER_ONE)
						val += value;
					else
						val -= value;

					System.out.println(val);
					Move move = findMove(selectedPin, val);
					if (move != null)
						try {
							System.out.println("making move");
							session.makeMove(move);
							updatePins();
							pinButton.get(new Integer(selectedPin)).setBackground(Color.white);
							selectedPin = val;
							pinButton.get(new Integer(val)).setBackground(Color.green);
							setEnabled(false);
						} catch (BackgammonException ex) {
							ex.printStackTrace();
						}
					if(session.isTurnFinished()) {
						session.switchTurns();
						updateDice();
					}
				}
			});
		}
		
		void setValue(int value) {
			this.value = value;
			ImageIcon diceIcon = new ImageIcon(dice[value-1].getScaledInstance(30,30, Image.SCALE_SMOOTH));
			setIcon(diceIcon);
		}
		void empty(){
			setIcon(null);
		}
	}
	
	private class PinNumberButton extends JButton {
		
		PinNumberButton(int i) {
			super(Integer.toString(i));
			setBorder(BorderFactory.createEmptyBorder());
			setBackground(Color.white);
			setFocusable(false);
		}
	}
	
	private class PlayerLabel extends JLabel {
		private Player.Identity id;
		
		public PlayerLabel(String name, Player.Identity id, ImageIcon img) {
			super(name, img, JLabel.RIGHT);
			
			this.id = id;
		}
		
		@Override
		public void paint(Graphics g) {
			setForeground(session.getCurrentPlayer().getIdentity() == id ? Color.green : Color.gray); 
			super.paint(g);
		}
	}
	
	private Container gameMenu() {
		if (gamePanel == null) {
			gamePanel = new JPanel();
			gamePanel.setLayout(new BorderLayout());
			gamePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
			JPanel diceSidePanel = new JPanel();
			diceSidePanel.setLayout(new GridLayout(4,1));
			((GridLayout)diceSidePanel.getLayout()).setVgap(10);
			diceSidePanel.add(Box.createHorizontalStrut(100));
			JPanel throwResultPanel = new JPanel();
			throwResultPanel.setLayout(new GridLayout(2,2));
			((GridLayout)throwResultPanel.getLayout()).setHgap(10);
			((GridLayout)throwResultPanel.getLayout()).setVgap(10);
			diceButton = new DiceButton[4];
			for (int i = 0; i < diceButton.length; i++) {
				diceButton[i] = new DiceButton();
				throwResultPanel.add(diceButton[i]);
			}
			diceSidePanel.add(throwResultPanel);
			//diceSidePanel.add(new MainMenuButton(this, "THROW DICE"));
			diceSidePanel.add(Box.createHorizontalStrut(100));
			gamePanel.add(diceSidePanel, BorderLayout.WEST);
			gamePanel.add(boardPanel(), BorderLayout.CENTER);
			//gamePanel.add(Box.createHorizontalStrut(100), BorderLayout.EAST);
			
			//playerOneLabel = new JLabel("Player 1", new ImageIcon(piece[0]), JLabel.RIGHT);
			playerOneLabel = new PlayerLabel("Player 1", Player.Identity.PLAYER_ONE, new ImageIcon(piece[0]));
			playerOneLabel.setHorizontalTextPosition(JLabel.LEADING);
			
			//playerTwoLabel = new JLabel("Player 2", new ImageIcon(piece[1]), JLabel.RIGHT);
			playerTwoLabel = new PlayerLabel("Player 2", Player.Identity.PLAYER_TWO, new ImageIcon(piece[1]));
			playerTwoLabel.setHorizontalTextPosition(JLabel.LEADING);
			setPlayerLabelColors();
			
			goal = new GoalButton[2];
			goal[0] = new GoalButton(0,session);
			goal[1] = new GoalButton(1,session);
			JPanel topBar = new JPanel();
			topBar.setLayout(new FlowLayout(FlowLayout.RIGHT));
			topBar.add(goal[0]);
			topBar.add(playerOneLabel);
			gamePanel.add(topBar, BorderLayout.NORTH);
			
			JPanel bottomBar = new JPanel();
			bottomBar.setLayout(new FlowLayout(FlowLayout.RIGHT));
			bottomBar.add(new MainMenuButton(this, "START OVER"));
			//bottomBar.add(Box.createHorizontalStrut(300));
			bottomBar.add(goal[1]);
			bottomBar.add(playerTwoLabel);
			gamePanel.add(bottomBar, BorderLayout.SOUTH);
		}
		updateDice();
		return gamePanel;
	}
	
	private void setPlayerLabelColors() {
		if (session.getCurrentPlayer().getIdentity().ordinal()==Player.Identity.PLAYER_ONE.ordinal()) {
			playerOneLabel.setForeground(Color.orange);
			playerTwoLabel.setForeground(Color.BLACK);
		} else {
			playerOneLabel.setForeground(Color.BLACK);
			playerTwoLabel.setForeground(Color.orange);
		}
	}
	
	private void appendPinButton(Frame frame, JPanel boardPanel, int i, GridBagConstraints c) {
		PinButton newButton = new PinButton(frame, session,i);
		boardPanel.add(newButton, c);
		pinButton.put(new Integer(i), newButton);
	}
	
	private void appendPinNumberButton(JPanel boardPanel, int i, GridBagConstraints c) {
		PinNumberButton newButton = new PinNumberButton(i);
		boardPanel.add(newButton, c);
		pinNumberButton.put(new Integer(i), newButton);
	}
	
	private Container boardPanel() {
		JPanel boardPanel = new JPanel();
		pinButton = new HashMap<Integer, PinButton>();
		pinNumberButton = new HashMap<Integer, PinNumberButton>();
		bar = new BarButton[2];
		bar[0] = new BarButton(0,session);
		bar[1] = new BarButton(1,session);
		boardPanel.setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		c.weighty = 0.3;
		c.gridy = 0;
		c.gridx = 0;
		for (int i = 13; i < 19; i++) {
			appendPinButton(this, boardPanel,i,c);
			c.gridx++;
		}
		c.weightx = 0.001;
		c.fill = GridBagConstraints.BOTH;
		boardPanel.add(bar[0], c);
		c.fill = GridBagConstraints.VERTICAL;
		c.gridx++;
		c.weightx = GridBagConstraints.RELATIVE;
		for (int i = 19; i < 25; i++) {
			appendPinButton(this, boardPanel,i,c);
			c.gridx++;
		}
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridy = 1;
		c.gridx = 0;
		c.weighty = 0.001; // ???
		for (int i = 13; i < 19; i++) {
			appendPinNumberButton(boardPanel,i, c);
			c.gridx++;
		}
		
		c.gridx++;
		for (int i = 19; i < 25; i++) {
			appendPinNumberButton(boardPanel,i, c);
			c.gridx++;
		}
		c.gridx = 0;
		c.gridy = 2;
		for (int i = 12; i > 6; i--) {
			appendPinNumberButton(boardPanel,i, c);
			c.gridx++;
		}
		
		c.gridx++;
		for (int i = 6; i > 0; i--) {
			appendPinNumberButton(boardPanel,i, c);
			c.gridx++;
		}
		c.gridx = 0;
		c.gridy = 3;
		c.weighty = 0.3;
		for (int i = 12; i > 6; i--) {
			appendPinButton(this, boardPanel,i,c);
			c.gridx++;
		}
		c.weightx = 0.001;
		c.fill = GridBagConstraints.BOTH;
		boardPanel.add(bar[1], c);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx++;
		c.weightx = GridBagConstraints.RELATIVE;
		for (int i = 6; i > 0; i--) {
			appendPinButton(this, boardPanel,i,c);
			c.gridx++;
		}
		boardPanel.setBackground(Color.black);
		
		return boardPanel;
	}
	
	private String readFile( String file ) throws IOException {
	    BufferedReader reader = new BufferedReader( new FileReader (file));
	    String         line = null;
	    StringBuilder  stringBuilder = new StringBuilder();
	    String         ls = System.getProperty("line.separator");

	    while( ( line = reader.readLine() ) != null ) {
	        stringBuilder.append( line );
	        stringBuilder.append( ls );
	    }
	    reader.close();
	    return stringBuilder.toString();
	}
	
	void updateDice() {
		for (int i = 0; i < 4; i++) {
			diceButton[i].empty();
			diceButton[i].setEnabled(true);
		}
		
		DiceResult[] diceResults = session.getDiceValues();
		for (int i = 0; i < diceResults.length; i++) {
			diceButton[i].setValue(diceResults[i].getResult());
		}
	}
	
	Move findMove(int selectedPin, int value) {
		List<Move> moves = session.getAvailableMoves(selectedPin);
		for(Move move : moves){
			if (move.getSource().getNumber() == selectedPin && move.getTarget().getNumber() == value)
				return move;
		}
		return null;
	}
	
	private void updatePins() {
		for (int i = 1; i <= pinButton.size(); i++) {
			pinButton.get(new Integer(i)).repaint();
		}
		bar[0].repaint();
		bar[1].repaint();
	}
}
